﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using NormalHistogram;
using NDK.Module.BLL;
using NDK.Module.DAL;
using NDK.Module.Model;
using NDK.Motion.Sys;

namespace NDK.Frm
{
    public partial class Frm_Statistics : Form
    {
        private static log4net.ILog m_Logger = log4net.LogManager.GetLogger("Frm_Statistics");
        private Action<double,  MeasureSize,  Chart,  bool , int , double , double , double , double , double , double[] , double[] , double , double , double , double > updateChartAction;
        List<Chart> chartList = new List<Chart>();
        List<ChartEx> chartExList = new List<ChartEx>();
        private HistoryDataServices dataService = new HistoryDataServices();
        MeasureSizeServices measureSizeServices = new MeasureSizeServices();
        static List<MeasureSize> measureSizeList; //= measureSizeServices.GetAll();
        public static ChartEx chartExStatic = new ChartEx();
        DataSet ds;
        private System.Windows.Forms.TableLayoutPanel tableLayoutPanel;
        Thread refreshChartThread ;//= new Thread[];
        Delegate updateChartDelegate;
        int userWidth = Screen.PrimaryScreen.Bounds.Width;
        int userHeight = Screen.PrimaryScreen.Bounds.Height;
        
        private Frm_Statistics()
        {
            InitializeComponent();

            CheckForIllegalCrossThreadCalls = false;
            InitStatisticChart();
          
            refreshChartThread = new Thread(new ThreadStart(RefreshChart));
            //refreshChartThread.Start();
            refreshChartThread.IsBackground = true;

            bgw_RefreshChart.RunWorkerAsync();
            updateChartAction = new Action<double, MeasureSize, Chart, bool, int, double, double, double, double, double, double[], double[], double, double, double, double>(NewUpdateChart);

        }
        /// <summary>
        /// 窗体对象实例，单例模式,保证整个工程只有一个实例
        /// </summary>
        private static Frm_Statistics _instance;
        private static readonly object singletonLock = new object();
        public static Frm_Statistics Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (singletonLock)
                    {
                        if (_instance == null)
                        {
                            _instance = new Frm_Statistics();
                        }
                    }
                }
                return _instance;
            }
        }
        private void InitStatisticChart()
        {
            int frToolbar1_Height = 86;
            int gap = 40;
            int yStart_Panel = gap;

            measureSizeList = measureSizeServices.GetAllByProjectNameAndIsJudging(Common.CurProType);
            if (measureSizeList == null)
            {
                m_Logger.Error("初始化统计图时异常！获取到该项目下没有需要判定的尺寸！");
                return;
            }
            int count = measureSizeList.Count;
            dtp_StartDate.Text = Common.startDate;
            dtp_StartTime.Text = Common.startTime;
            //根据尺寸数量和屏幕分辨率决定生成几行几列的TableLayoutPanel
            // 
            // tableLayoutPanel
            // 
            this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
            //this.tableLayoutPanel.Name = "tableLayoutPanel";
            this.tableLayoutPanel.Size = new System.Drawing.Size(206, 117);
            this.tableLayoutPanel.TabIndex = 29;
            this.tableLayoutPanel.Margin = new System.Windows.Forms.Padding(10);
            this.Controls.Add(this.tableLayoutPanel);

            tableLayoutPanel.Width = userWidth;
            //tableLayoutPanel.Width = this.Width;
            tableLayoutPanel.Height = userHeight - frToolbar1_Height - panel_Statistics.Height - 10;
            //tableLayoutPanel.Height = this.Height - panel_Statistics.Height - 10;
            tableLayoutPanel.Location = new Point(0, panel_Statistics.Height);

            this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(SizeType.Percent, 50F));
            this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(SizeType.Percent, 50F));
            this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(SizeType.Percent, 50F));
            this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(SizeType.Percent, 50F));
            this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(SizeType.Percent, 50F));
            this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(SizeType.Percent, 50F));
            this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(SizeType.Percent, 50F));

            this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(SizeType.Percent, 50F));
            this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(SizeType.Percent, 50F));
            this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(SizeType.Percent, 50F));
            this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(SizeType.Percent, 50F));
            this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(SizeType.Percent, 50F));
            //tableLayoutPanel.Dock = DockStyle.Fill;

            for (int i = 0; i < count; i++)
            {
                MeasureSize measureSize = measureSizeList[i];
                Chart chart = new Chart();

                //chart.Location = new System.Drawing.Point(60, 22);
                //chart.Width = userWidth /( count);
                //chart.Width = userHeight / count;
                // 
                // chart
                // 
                System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
                System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
                System.Windows.Forms.DataVisualization.Charting.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series();
                System.Windows.Forms.DataVisualization.Charting.Series series2 = new System.Windows.Forms.DataVisualization.Charting.Series();
                System.Windows.Forms.DataVisualization.Charting.Series series3 = new System.Windows.Forms.DataVisualization.Charting.Series();


                chart.BackColor = Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(238)))), ((int)(((byte)(239)))));
                chartArea.BackColor = Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(238)))), ((int)(((byte)(239)))));
                chartArea.Name = "ChartArea_" + measureSize.SizeName;
                chart.ChartAreas.Add(chartArea);
                legend1.BackColor = Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(238)))), ((int)(((byte)(239)))));
                legend1.BorderDashStyle = ChartDashStyle.Dash;
                legend1.Docking = Docking.Top;
                legend1.Name = "Legend_" + measureSize.SizeName;
                chart.Legends.Add(legend1);

                series1.BorderColor = Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(238)))), ((int)(((byte)(239)))));
                series1.ChartArea = "ChartArea_" + measureSize.SizeName;
                series1.ChartType = SeriesChartType.FastLine;
                series1.Legend = "Legend_" + measureSize.SizeName;
                series1.Name = measureSize.SizeName;
                series1.YValuesPerPoint = 6;
                series1.BorderWidth = 1;
                series2.ChartArea = "ChartArea_" + measureSize.SizeName;
                series2.ChartType = SeriesChartType.FastLine;
                series2.Legend = "Legend_" + measureSize.SizeName;
                series2.Name = "UpperLimit";
                series2.BorderWidth = 1;
                series3.ChartArea = "ChartArea_" + measureSize.SizeName;
                series3.ChartType = SeriesChartType.FastLine;
                series3.Legend = "Legend_" + measureSize.SizeName;
                series3.Name = "LowerLimit";
                series3.BorderWidth = 1;
                chart.Series.Add(series1);
                chart.Series.Add(series2);
                chart.Series.Add(series3);
                chart.Text = "chart_" + measureSize.SizeName;
                chart.Visible = true;
                chart.Dock = DockStyle.Fill;


                chart.Name = "chart_" + measureSizeList[i].SizeName;
                this.Controls.Add(chart);
                chartList.Add(chart);
                chart.MouseClick += chart_MouseClick;

                //TableLayoutPanel
                int rowIndex = i / 7;
                int columIndex = i % 7;
                this.tableLayoutPanel.Controls.Add(chart, columIndex, rowIndex);

                ChartEx chartEx = new ChartEx();
                chartEx.chart = chart;
                chartEx.row = rowIndex;
                chartEx.column = columIndex;

                chartExList.Add(chartEx);
                this.tableLayoutPanel.Refresh();
            }
        }

        void chart_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                Chart chart = (Chart)sender;

                string path = string.Empty;//文件夹路径
                string fileNameExt = chart.Name;//文件名
                System.Windows.Forms.SaveFileDialog sfd = new System.Windows.Forms.SaveFileDialog();
                sfd.RestoreDirectory = true;
                sfd.Title = "图片另存为";
                sfd.FileName = sfd.FileName + chart.Name + ".jpg";
                sfd.Filter = "图片类型 (*.bmp;*.tif;*.png;*.jpg;*.apd)|*.bmp;*.tif;*.png;*.jpg;*.apd|Bitmaps (*.bmp)|*.bmp|TIFF files (*.tif)|*.tif|PNG files (*.png)|*.png|JPEG files (*.jpg)|*.jpg|AIPD files (*.apd)|*.apd||";
                if (sfd.ShowDialog() == DialogResult.OK)
                {

                    path = sfd.FileName.ToString(); //获得文件路径 

                    fileNameExt = path.Substring(path.LastIndexOf("\\") + 1); //获取文件名，不带路径
                    chart.SaveImage(path, ChartImageFormat.Png);
                }
            }
        }
        void chart_MouseClick(object sender, MouseEventArgs e)
        {
            Chart chart = (Chart)sender;
            ChartEx chartEx = new ChartEx();
            foreach (ChartEx chartExTemp in chartExList)
            {
                if (chartExTemp.chart.Text == chart.Text)
                {
                    chartEx = chartExTemp;
                    break;
                }
            }
            chart.MouseUp += chart_MouseUp;
            Dlg_ShowChartDetails showChartDetails = new Dlg_ShowChartDetails();
            showChartDetails.DataChart = chartEx;
            chartEx.chart.MouseClick -= chart_MouseClick;
            if (showChartDetails.ShowDialog(this) == DialogResult.Abort)
            {
                chart.MouseUp -= chart_MouseUp;
                chartExStatic.chart.MouseClick += chart_MouseClick;
                this.tableLayoutPanel.Controls.Add(chartExStatic.chart, chartExStatic.column, chartExStatic.row);
            }

        }

        private void Frm_Statistics_Load(object sender, EventArgs e)
        {
  
        }

        #region 截屏
        public void CaptureScreen()
        {
            //屏幕宽
            int userWidth = Screen.PrimaryScreen.Bounds.Width;
            //屏幕高
            int userHeight = Screen.PrimaryScreen.Bounds.Height;
            //按照屏幕宽高创建位图
            Image img = new Bitmap(userWidth, userHeight);
            //从一个继承自Image类的对象中创建Graphics对象
            Graphics gc = Graphics.FromImage(img);
            //抓屏并拷贝到myimage里
            gc.CopyFromScreen(new Point(0, 0), new Point(0, 0), new Size(userWidth, userHeight));
            //this.BackgroundImage = img;
            //保存位图
            string path = string.Empty;//文件夹路径
            string fileNameExt = "Capture";//文件名
            System.Windows.Forms.SaveFileDialog sfd = new System.Windows.Forms.SaveFileDialog();
            sfd.RestoreDirectory = true;
            sfd.Title = "图片另存为";
            sfd.FileName = sfd.FileName + fileNameExt + ".jpg";
            sfd.Filter = "图片类型 (*.bmp;*.tif;*.png;*.jpg;*.apd)|*.bmp;*.tif;*.png;*.jpg;*.apd|Bitmaps (*.bmp)|*.bmp|TIFF files (*.tif)|*.tif|PNG files (*.png)|*.png|JPEG files (*.jpg)|*.jpg|AIPD files (*.apd)|*.apd||";
            if (sfd.ShowDialog() == DialogResult.OK)
            {

                path = sfd.FileName.ToString(); //获得文件路径 

                fileNameExt = path.Substring(path.LastIndexOf("\\") + 1); //获取文件名，不带路径
                img.Save(path);
            }

        }
        private void btn_Capture_ButtonClick()
        {
            CaptureScreen();
        } 
        #endregion

        #region 数据导出
        public static void Export2CSV(DataSet ds, string tableName, bool containColumName, string fileName)
        {
            string csvStr = ConverDataSet2CSV(ds, tableName, containColumName);
            if (csvStr == "") return;
            FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite);
            //将string转换成byte[]
            byte[] csvArray = Encoding.ASCII.GetBytes(csvStr.ToCharArray(), 0, csvStr.Length - 1);
            fs.Write(csvArray, 0, csvStr.Length - 1);
            fs.Close();
            fs = null;
        }
        /// <summary>
        /// 将指定的数据集中指定的表转换成CSV字符串
        /// </summary>
        /// <param name="ds"></param>
        /// <param name="tableName"></param>
        /// <returns></returns>
        private static string ConverDataSet2CSV(DataSet ds, string tableName, bool containColumName)
        {
            //首先判断数据集中是否包含指定的表
            if (ds == null || !ds.Tables.Contains(tableName) || ds.Tables[tableName].Rows.Count <= 0)
            {
                MessageBox.Show("指定的数据集为空或不包含要写出的数据表！", "系统提示：", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                return "";
            }
            string csvStr = "Dim,";
            //下面写出数据
            DataTable tb = ds.Tables[tableName];
            //写表名
            //csvStr += tb.TableName + "\n";
            //第一步：写出列名
            if (containColumName)
            {
                //列名
                foreach (DataColumn column in tb.Columns)
                {
                    csvStr += "\"" + column.ColumnName + "\"" + ",";
                }
                csvStr = csvStr.Remove(csvStr.LastIndexOf(","), 1);
                csvStr += "\n";
                //USL
                csvStr += "USL,";
                int i = 0;
                foreach (DataColumn column in tb.Columns)
                {
                    csvStr += "\"" + ((measureSizeList[i].UpperDeviation + measureSizeList[i].NormValue).ToString() + "\"" + ",");
                    i++;
                }
                csvStr = csvStr.Remove(csvStr.LastIndexOf(","), 1);
                csvStr += "\n";
                //Norm
                csvStr += "Norm,";
                i = 0;
                foreach (DataColumn column in tb.Columns)
                {
                    csvStr += "\"" + ((measureSizeList[i].NormValue).ToString() + "\"" + ",");
                    i++;
                }
                csvStr = csvStr.Remove(csvStr.LastIndexOf(","), 1);
                csvStr += "\n";
                //LSL
                csvStr += "LSL,";
                i = 0;
                foreach (DataColumn column in tb.Columns)
                {
                    csvStr += "\"" + ((measureSizeList[i].NormValue - measureSizeList[i].LowerDeviation).ToString() + "\"" + ",");
                    i++;
                }
                csvStr = csvStr.Remove(csvStr.LastIndexOf(","), 1);
                csvStr += "\n";

            }

            //第二步：写出数据
            int j = 0;
            foreach (DataRow row in tb.Rows)
            {
                csvStr += (++j).ToString() + ",";
                foreach (DataColumn column in tb.Columns)
                {
                    if (row[column].ToString() == "") return csvStr;
                    csvStr += "\"" + row[column].ToString() + "\"" + ",";
                }
                csvStr = csvStr.Remove(csvStr.LastIndexOf(","), 1);
                csvStr += "\n";
            }
            return csvStr;
        }
        private void btn_ExportCsv_Click(object sender, EventArgs e)
        {
            btn_ExportCsv.Caption1 = "导出中";
            btn_ExportCsv.Enabled = false;
            Task.Factory.StartNew(() =>
            {
                try
                {
                    //查询条件
                    string startTime = dtp_StartDate.Text + " " + DateTime.Parse(dtp_StartTime.Text).ToString("HH:mm:ss");
                    string endTime = dtp_EndDate.Text + " " + DateTime.Parse(dtp_EndTime.Text).ToString("HH:mm:ss");
                    string SN = tb_SN.Text.Trim();
                    //测量尺寸数，等于column数
                    int columnCount = measureSizeList.Count;
                    //创建一个新表，用于存放所有尺寸数据
                    DataSet ds = new DataSet();
                    ds.Tables.Add();
                    //创建一个表组，用于存放单个尺寸数据
                    DataSet[] dataSets = new DataSet[columnCount];
                    //将表组的数据，组合到一个表中
                    for (int i = 0; i < columnCount; i++)
                    {
                        //SQLiteUtils.WaitForRead();
                        dataSets[i] = dataService.GetSpecifiedListByTimeAndSNAndProject(measureSizeList[i].ID, startTime, endTime, SN, Common.ProjectName, "");//.Tables[0].DefaultView.Sort(;
                        //SQLiteUtils.ReleaseReadLock();
                        if (dataSets[i] == null || dataSets[i].Tables[0].Rows.Count <= 0) continue;
                        DataColumn dc = new DataColumn(measureSizeList[i].SizeName);
                        ds.Tables[0].Columns.Add(dc);
                        for (int j = 0; j < dataSets[i].Tables[0].Rows.Count; j++)
                        {
                            ds.Tables[0].Rows.Add();
                            ds.Tables[0].Rows[j][measureSizeList[i].SizeName] = dataSets[i].Tables[0].Rows[j]["Value"];
                        }
                        dataSets[i].Dispose();
                    }
                    Export2CSV(ds, ds.Tables[0].TableName, true, Common.dataSavePath + "\\" + DateTime.Now.ToString("HH-mm-ss") + ".csv");

                    ds.Dispose();

                    btn_ExportCsv.Caption1 = "Export";
                    btn_ExportCsv.Enabled = true;
                }
                catch (Exception exc)
                {
                }
            });

        } 
        #endregion

        #region 刷新chart
        bool isRefreshChart = false;
        private void timer1_Tick(object sender, EventArgs e)
        {
            lbl_Total.Text = "Total:" + Common.TotalCount;
            lbl_OK.Text = "OK:" + (Common.TotalCount - Common.NGCount);
            lbl_NG1.Text = "NG:" + Common.NGCount;
            lbl_Yield.Text = "Yield:" + (((Common.TotalCount - Common.NGCount) / Convert.ToDouble(Common.TotalCount)) * 100).ToString("f2") + "%";

            //if (Common.isStatisticsFromShow == true)
            //{
            //    isRefreshChart = true;
            //    //RefreshChartAction();
            //}

        }
        private void btn_Refresh_Click(object sender, EventArgs e)
        {
            //RefreshChart();
            RefreshChartTask();
            //RefreshChartAction();
        }
        //刷新chart线程函数
        bool iAmRunning = false;
        private void  RefreshChart()
        {
            while (MachineStatusManager.CurrentMachineStatus != MachineStatus.Quit)
            {
                if (Common.isStatisticsFromShow == true && iAmRunning == false)
                {
                        //RefreshChartAction();
                        RefreshChartTask();
                        Thread.Sleep(2000);
                        iAmRunning = false;
                        isRefreshChart = false;
                }
                Thread.Sleep(5);
                Application.DoEvents();
            }
        } 
        private void RefreshChartAction()
        {
            iAmRunning = true;
            int NGCount = 0;
            int OKCount = 0;
            int Total = 0;
            double Yield = 0.0;

            lbl_Total.Text = "Total:" + Common.TotalCount.ToString();
            lbl_NG1.Text = "NG:" + Common.NGCount.ToString();
            lbl_OK.Text = "OK:" + (Common.TotalCount - Common.NGCount).ToString();
            if (Common.TotalCount > 0)
            {
                lbl_Yield.Text = "Yield:" + ((Common.TotalCount - Common.NGCount) / Convert.ToDouble(Common.TotalCount)).ToString("p");
            }
            else
            {
                lbl_Yield.Text = "Yield:" + "0%";
            }
            //DataSet ds = dataService.GetList("Judgement = 'OK'");
            //OKCount = ds.Tables[0].Rows.Count;
            //ds = dataService.GetList("Judgement = 'NG'");
            //NGCount = ds.Tables[0].Rows.Count;
            //Total = NGCount + OKCount;
            //if (Total > 0)
            //{
            //    Yield = OKCount / Convert.ToDouble(NGCount + OKCount);
            //}
            //else
            //{
            //    Yield = 0;
            //}

            //lbl_Total.Text = "Total:" + (Total);
            //lbl_Yield.Text = "Yield:" + (Yield * 100).ToString("f2") + "%";
            //lbl_OK.Text = "OK:" + OKCount;
            //lbl_NG1.Text = "NG1:" + NGCount;

            try
            {
                //DataSet ds;
                //时间，条码，类型
                string startTime = dtp_StartDate.Text + " " + DateTime.Parse(dtp_StartTime.Text).ToString("HH:mm:ss");
                string endTime = dtp_EndDate.Text + " " + DateTime.Parse(dtp_EndTime.Text).ToString("HH:mm:ss");
                string SN = tb_SN.Text.Trim();


                #region Refresh HistoryData
                if (cb_ChartType.Text.Trim().Equals("HistoryData"))
                {
                    foreach (MeasureSize measureSize in measureSizeList)
                    {
                        //Task.Factory.StartNew(() =>
                        //{
                        foreach (Chart chart in chartList)
                        {
                            ////chart.BeginInvoke(new Action(() =>
                            ////{
                            if (chart.Text.Contains(measureSize.SizeName))
                            {
                                
                                //查询对应尺寸的多有数据
                                //SQLiteUtils.WaitForRead();
                                ds = dataService.GetSpecifiedListByTimeAndSNAndProject(measureSize.ID, startTime, endTime, SN, Common.ProjectName, "");
                                //SQLiteUtils.ReleaseReadLock();
                                //排除异常值
                                DataRow[] drs = ds.Tables[0].DefaultView.ToTable().Select("Value < '999' and Value > '0'");
                                //如果有正常值，将其放入DataTable
                                DataTable dt = new DataTable();
                                DataView dv = new DataView();
                                if (drs != null && drs.Count() > 0)
                                {
                                    dt = drs.CopyToDataTable();
                                    //将DataTable中的Value列绑定到DataView
                                    dv = new DataView(dt.DefaultView.ToTable(true, "Value"));
                                }
                                if (dt != null)
                                {

                                    chart.Series[0].ChartType = SeriesChartType.FastLine;
                                    chart.Series[1].ChartType = SeriesChartType.FastLine;
                                    chart.Series[2].ChartType = SeriesChartType.FastLine;
                                    chart.Series[0]["PointWidth"] = "1.0";
                                    chart.Series[0].BorderWidth = 1;
                                    chart.ChartAreas[0].AxisY.Enabled = AxisEnabled.True;
                                    chart.ChartAreas[0].AxisX.Enabled = AxisEnabled.True;
                                    chart.ChartAreas[0].AxisX.LabelStyle.Enabled = false;
                                    chart.ChartAreas[0].AxisX.MajorGrid.Enabled = false;
                                    chart.ChartAreas[0].AxisY.MajorGrid.Enabled = false;
                                    chart.ChartAreas[0].AxisY.LabelStyle.Format = "f3";
                                    chart.Legends[0].Enabled = true;
                                    chart.Titles.Clear();
                                    //将DataView
                                    chart.Series[0].Points.DataBindY(dv);
                                    double yMax = 0;
                                    double yMin = 0;
                                    double U = measureSize.UpperDeviation + measureSize.NormValue;
                                    double L = -measureSize.LowerDeviation + measureSize.NormValue;
                                    double dMax = U;
                                    double dMin = L;
                                    if (dt.Rows.Count > 1)
                                    {
                                        dMax = dt.AsEnumerable().Select(t => t.Field<double>("Value")).Max();
                                        dMin = dt.AsEnumerable().Select(t => t.Field<double>("Value")).Min();
                                    }
                                    yMax = dMax > U ? dMax : U;
                                    yMin = dMin < L ? dMin : L;
                                    chart.ChartAreas[0].AxisY.Maximum = yMax * 1.01;
                                    chart.ChartAreas[0].AxisY.Minimum = yMin * 0.99;
                                    chart.ChartAreas[0].AxisX.Maximum = double.NaN;
                                    chart.ChartAreas[0].AxisX.Minimum = double.NaN;



                                    List<double> upperDeviation = new List<double>();
                                    List<double> lowerDeviation = new List<double>();
                                    for (int j = 0; j < dv.Count; j++)
                                    {
                                        upperDeviation.Add(measureSize.UpperDeviation + measureSize.NormValue);
                                        lowerDeviation.Add(-measureSize.LowerDeviation + measureSize.NormValue);
                                    }

                                    chart.Series[1].Points.DataBindY(upperDeviation);
                                    chart.Series[2].Points.DataBindY(lowerDeviation);

                                    chart.Refresh();
                                }
                            }
                            //}));

                        }
                        //});
                    }

                }
                #endregion


                #region Refresh CPK
                if (cb_ChartType.Text.Trim().Equals("CPK"))
                {
                    foreach (MeasureSize measureSize in measureSizeList)
                    {
                        bool dataOverRangeFlag = false;
                        int groupCount = 40 + 1;
                        //公差
                        double plusTolerance = measureSize.UpperDeviation;
                        double negTolerance = -measureSize.LowerDeviation;
                        double norm = measureSize.NormValue;
                        double USL = norm + plusTolerance;
                        double LSL = norm + negTolerance;
                        double groupInterval = Math.Round((plusTolerance - negTolerance) / 20, 3);

                        double[] coordinateX = new double[groupCount];
                        double[] coordinateY = new double[groupCount];
                        List<double> frequency = new List<double>();
                        //根据尺寸名称匹配对应chart
                        foreach (Chart chart in chartList)
                        {
                            Application.DoEvents();
                            if (chart.Text.Substring(6) == measureSize.SizeName)
                            {
                                Application.DoEvents();
                                Thread.Sleep(10);
                                int ID = measureSizeServices.GetModel(measureSize.SizeName).ID;
                                chart.Series[0].Points.Clear();
                                //查询数据
                                ds = dataService.GetSpecifiedListByTimeAndSNAndProject(measureSize.ID, startTime, endTime, SN, Common.ProjectName, "");
                                Application.DoEvents();

                                List<double> doubleList = new List<double>();
                                //将查询到的数据转换成数组
                                Total = 0;
                                NGCount = 0;
                                OKCount = 0;
                                int rows = ds.Tables[0].Rows.Count;
                                double value;
                                string judgeResult;
                                for (int i = 0; i < rows; i++)
                                {
                                    double.TryParse(ds.Tables[0].Rows[i]["Value"].ToString(), out value);
                                    judgeResult = ds.Tables[0].Rows[i]["Judgement"].ToString();
                                    //if (value < norm + 3 * negTolerance || value > norm + 3 * plusTolerance) continue;//超3倍公差不参与判定
                                    if (judgeResult == JUDGEMENT_RESULT.EXCEPTION.ToString()) continue;//超3倍公差不参与判定

                                    if (judgeResult == JUDGEMENT_RESULT.NG.ToString())
                                    //if (value < norm + negTolerance || value > norm + plusTolerance)
                                    {
                                        NGCount++;
                                    }
                                    if (judgeResult == JUDGEMENT_RESULT.OK.ToString())
                                    {
                                        OKCount++;
                                    }
                                    Total++;
                                    doubleList.Add(value);
                                }
                                Application.DoEvents();
                                if (Total > 0)
                                {
                                    Yield = (Total - NGCount) / Convert.ToDouble(Total);
                                }
                                else
                                {
                                    Yield = 0;
                                }
                                rows = doubleList.Count;
                                double[] singleDemessionData = new double[rows];
                                for (int i = 0; i < rows; i++)
                                {
                                    singleDemessionData[i] = (doubleList[i]);
                                }
                                Application.DoEvents();
                                //计算cpk起点和终点
                                double startPoint = 0;
                                double endPoint = 0;
                                for (int j = 0; j < groupCount; j++)
                                {
                                    if (negTolerance != 0)
                                    {
                                        startPoint = LSL - 10 * groupInterval;
                                        endPoint = USL + 10 * groupInterval;
                                    }
                                    else
                                    {
                                        startPoint = 0;
                                        endPoint = USL + 20 * groupInterval;
                                    }
                                }
                                Application.DoEvents();
                                //计算分布
                                if (!NormalCalculation.getNormDistXY(singleDemessionData, startPoint, groupInterval, groupCount, out coordinateX, out coordinateY, out frequency))
                                    break;
                                Application.DoEvents();
                                for (int j = 0; j < groupCount; j++)
                                {
                                    coordinateX[j] += groupInterval / 2;
                                }
                                Application.DoEvents();
                                double stDev = NormalCalculation.getStDev(singleDemessionData);
                                double dataAvg = NormalCalculation.getAverage(singleDemessionData);
                                double dataMax = NormalCalculation.getMax(singleDemessionData);
                                double dataMin = NormalCalculation.getMin(singleDemessionData);
                                //数据是否超出范围
                                if (dataMax < coordinateX[0] || dataMin > coordinateX[groupCount - 1])
                                    dataOverRangeFlag = true;

                                for (int j = 0; j < groupCount; j++)
                                {
                                    //显示
                                    if (coordinateX[j] < dataMin || coordinateX[j] > dataMax)
                                        coordinateY[j] = -1;
                                }
                                Application.DoEvents();

                                chart.Series[1].Points.Clear();
                                chart.Series[2].Points.Clear();
                                double yMaxValue = coordinateY.Max();
                                double yMinValue = coordinateY.Min();
                                if (yMaxValue - yMinValue < 0.000001) continue;
                                if (yMaxValue < 0)
                                {
                                    chart.ChartAreas[0].AxisY.Maximum = yMaxValue * 0.9;
                                }
                                else
                                {
                                    chart.ChartAreas[0].AxisY.Maximum = yMaxValue * 1.1;
                                }
                                chart.ChartAreas[0].AxisY.Minimum = 0;


                                if (LSL != 0)
                                {

                                    //设置下限
                                    chart.Series[1].Points.AddXY(LSL, 0);
                                    chart.Series[1].Points.AddXY(LSL, yMaxValue);
                                    //设置上限
                                    chart.Series[2].Points.AddXY(USL, 0);
                                    chart.Series[2].Points.AddXY(USL, yMaxValue);
                                }
                                else
                                {
                                    //设置上限
                                    chart.Series[2].Points.AddXY(USL, 0);
                                    chart.Series[2].Points.AddXY(USL, yMaxValue);
                                }
                                chart.ChartAreas[0].AxisX.Maximum = endPoint;
                                chart.ChartAreas[0].AxisX.Minimum = startPoint;
                                //chart.ChartAreas[0].AxisY.Minimum = 0;

                                //得到CPK
                                double LCpk = 0;
                                double UCpk = 0;
                                double Cpk = 0;
                                double Cp = 0;
                                double Ca = 0;
                                if (plusTolerance != 0 && negTolerance != 0)
                                {
                                    double T = plusTolerance - negTolerance;
                                    UCpk = (USL - dataAvg) / (3 * stDev);
                                    LCpk = (dataAvg - LSL) / (3 * stDev);
                                    Ca = 2 * (dataAvg - norm) / T;
                                    Cpk = ((UCpk >= LCpk) ? LCpk : UCpk);
                                    Cp = T / (6 * stDev);
                                    //Cpk = Cp * (1 - Math.Abs(Ca));
                                }
                                else if (plusTolerance != 0 && negTolerance == 0)
                                {
                                    UCpk = (USL - dataAvg) / (3 * stDev);
                                    Cpk = UCpk;
                                    Cp = UCpk;
                                }
                                //chart属性设置
                                string title = string.Empty;
                                chart.Series[0].ChartType = SeriesChartType.RangeColumn;
                                chart.Series[1].ChartType = SeriesChartType.Line;
                                chart.Series[2].ChartType = SeriesChartType.Line;
                                chart.Series[0]["PointWidth"] = "1";
                                chart.Series[0].BorderWidth = 0;
                                chart.ChartAreas[0].AxisY.Enabled = AxisEnabled.False;
                                chart.ChartAreas[0].AxisX.Enabled = AxisEnabled.True;
                                chart.ChartAreas[0].AxisX.LabelStyle.Enabled = true;
                                chart.ChartAreas[0].AxisX.MajorGrid.Enabled = false;
                                chart.ChartAreas[0].AxisY.MajorGrid.Enabled = false;
                                chart.ChartAreas[0].AxisX.LabelStyle.Font = new System.Drawing.Font("微软雅黑", 7);


                                chart.Titles.Clear();
                                chart.Titles.Add("");
                                chart.Legends[0].Enabled = false;
                                //显示CPK信息到title
                                if (!dataOverRangeFlag)
                                {//LSL/NORM/USL
                                    title = string.Format("{0} \t\t\t\t {1} \n({2}/{3}/{4}) \n Cp/Cpk({5}/{6})", measureSize.SizeName, Yield.ToString("p"), LSL, norm, USL, Cp.ToString("f3"), Cpk.ToString("f3"));
                                    chart.Series[0].Points.DataBindXY(coordinateX, coordinateY);
                                    chart.Titles[0].Text = title;
                                }
                                else
                                {
                                    for (int j = 0; j < groupCount; j++)
                                        coordinateY[j] = 0;
                                    chart.Series[0].Points.DataBindXY(coordinateX, coordinateY);
                                    title = "数据异常";
                                    chart.Titles[0].Text = title;
                                    break;
                                }
                                Application.DoEvents();
                                for (int j = 0; j < groupCount; j++)
                                {
                                    if (coordinateX[j] < LSL || coordinateX[j] > USL)
                                    //if (coordinateX[j])
                                    {
                                        chart.Series[0].Points[j].Color = Color.Red;
                                    }
                                    else
                                    {
                                        chart.Series[0].Points[j].Color = Color.DarkSlateBlue;
                                    }
                                }
                                //Application.DoEvents();
                            }
                        }
                    }
                }
                //iAmRunning = false;
                #endregion
            }
            catch (Exception ex)
            {
                iAmRunning = false;
                isRefreshChart = false;
            }
            iAmRunning = false;
            isRefreshChart = false;
        }
        private void RefreshChartTask()
        {
            iAmRunning = true;
           

            lbl_Total.Text = "Total:" + Common.TotalCount.ToString();
            lbl_NG1.Text = "NG:" + Common.NGCount.ToString();
            lbl_OK.Text = "OK:" + (Common.TotalCount - Common.NGCount).ToString();
            if (Common.TotalCount > 0)
            {
                lbl_Yield.Text = "Yield:" + ((Common.TotalCount - Common.NGCount) / Convert.ToDouble(Common.TotalCount)).ToString("p");
            }
            else
            {
                lbl_Yield.Text = "Yield:" + "0%";
            }
           

            try
            {
                //DataSet ds;
                //时间，条码，类型
                string startTime = dtp_StartDate.Text + " " + DateTime.Parse(dtp_StartTime.Text).ToString("HH:mm:ss");
                //string startTime = "2018-01-01 " + DateTime.Parse(dtp_StartTime.Text).ToString("HH:mm:ss");
                string endTime = dtp_EndDate.Text + " " + DateTime.Parse(dtp_EndTime.Text).ToString("HH:mm:ss");
                string SN = tb_SN.Text.Trim();


                #region Refresh HistoryData
                if (cb_ChartType.Text.Trim().Equals("HistoryData"))
                {
                    foreach (MeasureSize measureSize in measureSizeList)
                    {
                        //Task.Factory.StartNew(() =>
                        //{
                        foreach (Chart chart in chartList)
                        {
                            ////chart.BeginInvoke(new Action(() =>
                            ////{
                            if (chart.Text.Contains(measureSize.SizeName))
                            {

                                //查询对应尺寸的多有数据
                                //SQLiteUtils.WaitForRead();
                                ds = dataService.GetSpecifiedListByTimeAndSNAndProject(measureSize.ID, startTime, endTime, SN, Common.ProjectName, "");
                                //SQLiteUtils.ReleaseReadLock();
                                //排除异常值
                                DataRow[] drs = ds.Tables[0].DefaultView.ToTable().Select("Value < '999' and Value > '0'");
                                //如果有正常值，将其放入DataTable
                                DataTable dt = new DataTable();
                                DataView dv = new DataView();
                                if (drs != null && drs.Count() > 0)
                                {
                                    dt = drs.CopyToDataTable();
                                    //将DataTable中的Value列绑定到DataView
                                    dv = new DataView(dt.DefaultView.ToTable(true, "Value"));
                                }
                                if (dt != null)
                                {

                                    chart.Series[0].ChartType = SeriesChartType.FastLine;
                                    chart.Series[1].ChartType = SeriesChartType.FastLine;
                                    chart.Series[2].ChartType = SeriesChartType.FastLine;
                                    chart.Series[0]["PointWidth"] = "1.0";
                                    chart.Series[0].BorderWidth = 1;
                                    chart.ChartAreas[0].AxisY.Enabled = AxisEnabled.True;
                                    chart.ChartAreas[0].AxisX.Enabled = AxisEnabled.True;
                                    chart.ChartAreas[0].AxisX.LabelStyle.Enabled = false;
                                    chart.ChartAreas[0].AxisX.MajorGrid.Enabled = false;
                                    chart.ChartAreas[0].AxisY.MajorGrid.Enabled = false;
                                    chart.ChartAreas[0].AxisY.LabelStyle.Format = "f3";
                                    chart.Legends[0].Enabled = true;
                                    chart.Titles.Clear();
                                    //将DataView
                                    chart.Series[0].Points.DataBindY(dv);
                                    double yMax = 0;
                                    double yMin = 0;
                                    double U = measureSize.UpperDeviation + measureSize.NormValue;
                                    double L = -measureSize.LowerDeviation + measureSize.NormValue;
                                    double dMax = U;
                                    double dMin = L;
                                    if (dt.Rows.Count > 1)
                                    {
                                        dMax = dt.AsEnumerable().Select(t => t.Field<double>("Value")).Max();
                                        dMin = dt.AsEnumerable().Select(t => t.Field<double>("Value")).Min();
                                    }
                                    yMax = dMax > U ? dMax : U;
                                    yMin = dMin < L ? dMin : L;
                                    chart.ChartAreas[0].AxisY.Maximum = yMax * 1.01;
                                    chart.ChartAreas[0].AxisY.Minimum = yMin * 0.99;
                                    chart.ChartAreas[0].AxisX.Maximum = double.NaN;
                                    chart.ChartAreas[0].AxisX.Minimum = double.NaN;



                                    List<double> upperDeviation = new List<double>();
                                    List<double> lowerDeviation = new List<double>();
                                    for (int j = 0; j < dv.Count; j++)
                                    {
                                        upperDeviation.Add(measureSize.UpperDeviation + measureSize.NormValue);
                                        lowerDeviation.Add(-measureSize.LowerDeviation + measureSize.NormValue);
                                    }

                                    chart.Series[1].Points.DataBindY(upperDeviation);
                                    chart.Series[2].Points.DataBindY(lowerDeviation);

                                    chart.Refresh();
                                }
                            }
                            //}));

                        }
                        //});
                    }

                }
                #endregion

                #region Refresh CPK
                if (cb_ChartType.Text.Trim().Equals("CPK"))
                {
                    int count = measureSizeList.Count;
                    int[] NGCount = new int[count];
                    int[] OKCount = new int[count];
                    int[] Total = new int[count];
                    double[] Yield = new double[count];
                    
                    bool[] dataOverRangeFlag = new bool[count];
                    int groupCount;
                    double[] plusTolerance = new double[count];
                    double[] negTolerance = new double[count];
                    double[] norm = new double[count];
                    double[] USL = new double[count];
                    double[] LSL = new double[count];
                    List<double[]> coordinateXList = new List<double[]>();
                    List<double[]> coordinateYList = new List<double[]>();
                    double[] startPoint = new double[count];
                    double[] endPoint= new double[count];
                    double[] stDev = new double[count]; 
                    double[] dataAvg = new double[count]; 

                    int index = 0;
                    foreach (MeasureSize measureSize in measureSizeList)
                    {
                        double[] coordinateY = new double[count];
                        double[] coordinateX = new double[count];
                        //coordinateXList.Add(coordinateX);
                        //coordinateYList.Add(coordinateY);

                        CalCPK(ref NGCount[index], ref OKCount[index], ref Total[index], ref Yield[index], startTime, endTime, SN, measureSize, out dataOverRangeFlag[index],
                            out groupCount, out plusTolerance[index], out negTolerance[index], out norm[index], out USL[index], out LSL[index], out coordinateX,
                            out coordinateY, out startPoint[index], out endPoint[index], out stDev[index], out dataAvg[index]);

                        NewUpdateChart(Yield[index], measureSize, chartList[index], dataOverRangeFlag[index],
                            groupCount, plusTolerance[index], negTolerance[index], norm[index], USL[index], LSL[index],
                            coordinateX, coordinateY, startPoint[index], endPoint[index], stDev[index], dataAvg[index]);
                        //Thread.Sleep(200);
                       index++;
                    }
                }
                //iAmRunning = false;
                #endregion
            }
            catch (Exception ex)
            {
                iAmRunning = false;
                isRefreshChart = false;
            }
            //iAmRunning = false;
            //isRefreshChart = false;
        }

        private  void NewUpdateChart(double Yield, MeasureSize measureSize, Chart chart, bool dataOverRangeFlag, int groupCount, double plusTolerance, double negTolerance, double norm, double USL, double LSL, double[] coordinateX, double[] coordinateY, double startPoint, double endPoint, double stDev, double dataAvg)
        {
            if (!tableLayoutPanel.InvokeRequired)
            {
                //chart.Series[0].Points.Clear();
                //chart.Series[1].Points.Clear();
                //chart.Series[2].Points.Clear();
                double yMaxValue = coordinateY.Max();
                double yMinValue = coordinateY.Min();
                if (yMaxValue - yMinValue < 0.000001) return;
                if (yMaxValue < 0)
                {
                    chart.ChartAreas[0].AxisY.Maximum = yMaxValue * 0.9;
                }
                else
                {
                    chart.ChartAreas[0].AxisY.Maximum = yMaxValue * 1.1;
                }
                chart.ChartAreas[0].AxisY.Minimum = 0;


                if (LSL != 0)
                {

                    //设置下限
                    chart.Series[1].Points.AddXY(LSL, 0);
                    chart.Series[1].Points.AddXY(LSL, yMaxValue);
                    //设置上限
                    chart.Series[2].Points.AddXY(USL, 0);
                    chart.Series[2].Points.AddXY(USL, yMaxValue);
                }
                else
                {
                    //设置上限
                    chart.Series[2].Points.AddXY(USL, 0);
                    chart.Series[2].Points.AddXY(USL, yMaxValue);
                }
                chart.ChartAreas[0].AxisX.Maximum = endPoint;
                chart.ChartAreas[0].AxisX.Minimum = startPoint;
                //chart.ChartAreas[0].AxisY.Minimum = 0;

                //得到CPK
                double LCpk = 0;
                double UCpk = 0;
                double Cpk = 0;
                double Cp = 0;
                double Ca = 0;
                if (plusTolerance != 0 && negTolerance != 0)
                {
                    double T = plusTolerance - negTolerance;
                    UCpk = (USL - dataAvg) / (3 * stDev);
                    LCpk = (dataAvg - LSL) / (3 * stDev);
                    Ca = 2 * (dataAvg - norm) / T;
                    Cpk = ((UCpk >= LCpk) ? LCpk : UCpk);
                    Cp = T / (6 * stDev);
                    //Cpk = Cp * (1 - Math.Abs(Ca));
                }
                else if (plusTolerance != 0 && negTolerance == 0)
                {
                    UCpk = (USL - dataAvg) / (3 * stDev);
                    Cpk = UCpk;
                    Cp = UCpk;
                }
                //chart属性设置
                string title = string.Empty;
                chart.Series[0].ChartType = SeriesChartType.RangeColumn;
                chart.Series[1].ChartType = SeriesChartType.Line;
                chart.Series[2].ChartType = SeriesChartType.Line;
                chart.Series[0]["PointWidth"] = "1";
                chart.Series[0].BorderWidth = 0;
                chart.ChartAreas[0].AxisY.Enabled = AxisEnabled.False;
                chart.ChartAreas[0].AxisX.Enabled = AxisEnabled.True;
                chart.ChartAreas[0].AxisX.LabelStyle.Enabled = true;
                chart.ChartAreas[0].AxisX.MajorGrid.Enabled = false;
                chart.ChartAreas[0].AxisY.MajorGrid.Enabled = false;
                chart.ChartAreas[0].AxisX.LabelStyle.Font = new System.Drawing.Font("微软雅黑", 7);


                chart.Titles.Clear();
                chart.Titles.Add("");
                chart.Legends[0].Enabled = false;
                //显示CPK信息到title
                if (!dataOverRangeFlag)
                {//LSL/NORM/USL
                    title = string.Format("{0} \t\t\t\t {1} \n({2}/{3}/{4}) \n Cp/Cpk({5}/{6})", measureSize.SizeName, Yield.ToString("p"), LSL, norm, USL, Cp.ToString("f3"), Cpk.ToString("f3"));
                    chart.Series[0].Points.DataBindXY(coordinateX, coordinateY);
                    chart.Titles[0].Text = title;
                }
                else
                {
                    for (int j = 0; j < groupCount; j++)
                        coordinateY[j] = 0;
                    chart.Series[0].Points.DataBindXY(coordinateX, coordinateY);
                    title = "数据异常";
                    chart.Titles[0].Text = title;
                    return;
                }
                Application.DoEvents();
                for (int j = 0; j < groupCount; j++)
                {
                    if (coordinateX[j] < LSL || coordinateX[j] > USL)
                    //if (coordinateX[j])
                    {
                        chart.Series[0].Points[j].Color = Color.Red;
                    }
                    else
                    {
                        chart.Series[0].Points[j].Color = Color.DarkSlateBlue;
                    }
                }
               
            }
            else
            {
                
                this.BeginInvoke(updateChartAction, new object[] { Yield,  measureSize,  chart,  dataOverRangeFlag,  groupCount,  plusTolerance, negTolerance,  norm,  USL,  LSL,  coordinateX,  coordinateY, startPoint,  endPoint,  stDev,  dataAvg });
                //this.Invoke(updateChartAction, new object[] { Yield, measureSize, chart, dataOverRangeFlag, groupCount, plusTolerance, negTolerance, norm, USL, LSL, coordinateX, coordinateY, startPoint, endPoint, stDev, dataAvg });
            }
        }

        private void CalCPK(ref int NGCount, ref int OKCount, ref int Total, ref double Yield, string startTime, string endTime, string SN, MeasureSize measureSize, out bool dataOverRangeFlag, out int groupCount, out double plusTolerance, out double negTolerance, out double norm, out double USL, out double LSL, out double[] coordinateX, out double[] coordinateY, out double startPoint, out double endPoint, out double stDev, out double dataAvg)
        {
            
            dataOverRangeFlag = false;
            groupCount = 40 + 1;
            //公差
            plusTolerance = measureSize.UpperDeviation;
            negTolerance = -measureSize.LowerDeviation;
            norm = measureSize.NormValue;
            USL = norm + plusTolerance;
            LSL = norm + negTolerance;
            double groupInterval = Math.Round((plusTolerance - negTolerance) / 20, 3);

            coordinateX = new double[groupCount];
            coordinateY = new double[groupCount];
            List<double> frequency = new List<double>();


            int ID = measureSizeServices.GetModel(measureSize.SizeName).ID;

            //查询数据
            ds = dataService.GetSpecifiedListByTimeAndSNAndProject(measureSize.ID, startTime, endTime, SN, Common.ProjectName, "");

            List<double> doubleList = new List<double>();
            //将查询到的数据转换成数组
            Total = 0;
            NGCount = 0;
            OKCount = 0;
            int rows = ds.Tables[0].Rows.Count;
            double value;
            string judgeResult;
            for (int i = 0; i < rows; i++)
            {
                double.TryParse(ds.Tables[0].Rows[i]["Value"].ToString(), out value);
                judgeResult = ds.Tables[0].Rows[i]["Judgement"].ToString();
                //if (value < norm + 3 * negTolerance || value > norm + 3 * plusTolerance) continue;//超3倍公差不参与判定
                if (judgeResult == JUDGEMENT_RESULT.EXCEPTION.ToString())//超3倍公差不参与判定
                {
                    dataAvg = 0;
                    endPoint = 0;
                    startPoint = 0;
                    stDev = 0;
                    continue;
                } 

                if (judgeResult == JUDGEMENT_RESULT.NG.ToString())
                //if (value < norm + negTolerance || value > norm + plusTolerance)
                {
                    NGCount++;
                }
                if (judgeResult == JUDGEMENT_RESULT.OK.ToString())
                {
                    OKCount++;
                }
                Total++;
                doubleList.Add(value);
            }
            if (Total > 0)
            {
                Yield = (Total - NGCount) / Convert.ToDouble(Total);
            }
            else
            {
                Yield = 0;
            }
            rows = doubleList.Count;
            double[] singleDemessionData = new double[rows];
            for (int i = 0; i < rows; i++)
            {
                singleDemessionData[i] = (doubleList[i]);
            }
            //计算cpk起点和终点
            startPoint = 0;
            endPoint = 0;
            for (int j = 0; j < groupCount; j++)
            {
                if (negTolerance != 0)
                {
                    startPoint = LSL - 10 * groupInterval;
                    endPoint = USL + 10 * groupInterval;
                }
                else
                {
                    startPoint = 0;
                    endPoint = USL + 20 * groupInterval;
                }
            }
            //计算分布
            if (!NormalCalculation.getNormDistXY(singleDemessionData, startPoint, groupInterval, groupCount, out coordinateX, out coordinateY, out frequency))
            {
                dataAvg = 0;
                endPoint = 0;
                startPoint = 0;
                stDev = 0;
                return;
            } 
            for (int j = 0; j < groupCount; j++)
            {
                coordinateX[j] += groupInterval / 2;
            }
            stDev = NormalCalculation.getStDev(singleDemessionData);
            dataAvg = NormalCalculation.getAverage(singleDemessionData);
            double dataMax = NormalCalculation.getMax(singleDemessionData);
            double dataMin = NormalCalculation.getMin(singleDemessionData);
            //数据是否超出范围
            if (dataMax < coordinateX[0] || dataMin > coordinateX[groupCount - 1])
                dataOverRangeFlag = true;

            for (int j = 0; j < groupCount; j++)
            {
                //显示
                if (coordinateX[j] < dataMin || coordinateX[j] > dataMax)
                    coordinateY[j] = -1;
            }
            
        }

        #endregion

        private void bgw_RefreshChart_DoWork(object sender, DoWorkEventArgs e)
        {
           RefreshChart();
           //await Task.Run(() => RefreshChartTask()); 

        }
    }
    public class ChartEx
    {
        public Chart chart;
        public int row;
        public int column;
    }
    public delegate void updateStatisticChartDelegate();
}
